package com.ruoyi.info.controller;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.CacheUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.info.service.ICmsCaptchaService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.util.IpUtils;
import com.ruoyi.util.entinfo.MessageUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

@Controller
public class IndexController extends BaseController {
    @Autowired
    private ICmsCaptchaService cmsCaptchaService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysPasswordService passwordService;


    // 发送短信验证码
    @PostMapping("/phoneCode")
    @ResponseBody
    public AjaxResult phoneCode(String username, String type, HttpServletRequest request) throws UnsupportedEncodingException {

        username = URLDecoder.decode(username, "UTF-8");
        username = username.replaceAll(" ", "");

        SysUser user = userService.selectUserByPhoneNumber(username);
        if(user == null && "login".equals(type)) { // 登录检查
            return AjaxResult.error("手机号码不存在");
        }

        String ip = IpUtils.getIpAddr(request);

        // 一小时内ip请求的次数
        Integer ipNum = Convert.toInt(CacheUtils.get(ip));
        if(ipNum == null) {
            ipNum = 0;
        }
        if(ipNum >= 5) {
            return AjaxResult.error("您所处的ip请求过于频繁，请稍后再试！");
        }

        Long now = System.currentTimeMillis();
        Long last = Convert.toLong(CacheUtils.get(username + "_TIME"));
        Integer uNum = Convert.toInt(CacheUtils.get(username + "_NUM"));

        if(last != null) {
            Long diff = now - last;
            // 小于1分钟
            if(diff < 60000) {
                return AjaxResult.error(username + "请求过于频繁，请一分钟后重试！");
            }
        }

        if(uNum == null) {
            uNum = 0;
        }

        if(uNum >= 5) {
            return AjaxResult.error(username + "短时间内进行了多次请求，请一小时后后重试！");
        }

        String code = cmsCaptchaService.createCaptcha(username);
        System.out.println("--------------------------------\n验证码：" + code);
        AjaxResult rs = MessageUtil.sendMsg(username, code);

        ipNum++;
        uNum++;
        CacheUtils.put(ip, ipNum);
        CacheUtils.put(username + "_TIME", now);
        CacheUtils.put(username + "_NUM", uNum);

        return rs;
    }

    // 手机登录
    @PostMapping("/phoneLogin")
    @ResponseBody
    public AjaxResult phoneLogin(String username, String code) {
        String msg = cmsCaptchaService.validateCaptcha(username, code);

        if(msg != null) {
            return AjaxResult.error(msg);
        }

        SysUser user = userService.selectUserByPhoneNumber(username);
        // 无密码登录
        UsernamePasswordToken token = new UsernamePasswordToken(user.getLoginName(), "_1234!@#$qwerQWER", true);

        Subject subject = SecurityUtils.getSubject();
        try
        {
            subject.login(token);
            return success();
        }
        catch (AuthenticationException e)
        {
             msg = "登录失败!";
            if (StringUtils.isNotEmpty(e.getMessage()))
            {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

    // 注册
    @PostMapping("/phoneRegister")
    @ResponseBody
    public AjaxResult phoneRegister(SysUser user, String verifyCode) {
        System.out.println(verifyCode+"----------------------->" + user);
        user.setUserType("01"); // 注册用户
        user.setPhonenumber(user.getUserName()); // 用户名就是手机号
        user.setLoginName(user.getUserName()); //


        // 验证短信验证码
        String msg = cmsCaptchaService.validateCaptcha(user.getUserName(), verifyCode);

        if(msg!= null) {
            return AjaxResult.error(msg);
        }

        if (!userService.checkLoginNameUnique(user))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
        }
        else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }

        user.setSalt(ShiroUtils.randomSalt());
        user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));

        return toAjax(userService.insertUser(user));
    }

    @GetMapping("/password")
    public String password() {
        return "password";
    }

    @PostMapping("/changePassword")
    @ResponseBody
    public AjaxResult changePassword(SysUser user, String verifyCode){

        String msg = cmsCaptchaService.validateCaptcha(user.getUserName(), verifyCode);

        if(msg!= null) {
            return AjaxResult.error(msg);
        }

        SysUser existUser = userService.selectUserByPhoneNumber(user.getUserName());
        if(existUser == null) {
            return AjaxResult.error("手机号码不存在");
        }

        existUser.setSalt(ShiroUtils.randomSalt());
        existUser.setPassword(passwordService.encryptPassword(existUser.getLoginName(), user.getPassword(), existUser.getSalt()));

        userService.updateUser(existUser);

        return AjaxResult.success();
    }

}
